home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Environments / PowerMacOberon feb96 / Source / Decoder.Mod (.txt) < prev    next >
Encoding:
Oberon Text  |  1996-01-25  |  40.0 KB  |  1,115 lines  |  [TEXT/.Ob4]

  1. Syntax12b.Scn.Fnt
  2. Syntax12.Scn.Fnt
  3. Syntax12i.Scn.Fnt
  4. Syntax10.Scn.Fnt
  5. Syntax14.Scn.Fnt
  6. MODULE Decoder;    (* mmb 25.12.90 / 31.5.94 *)(* MAH 25 Jul 94  Byte ordering changed *)
  7.     (* MK 24 0ct 95 extended reference information *)
  8.     IMPORT
  9.         Texts, Files, TextFrames, Viewers, MenuViewers, Oberon, SYSTEM, Out;
  10.     CONST
  11.         (* formats *)
  12.         LIxAAxLK = 0; BOxBIxBDxAAxLK = 1; BOxBIxLK = 2; LKu = 3; Rcu = 4; None = 6; BFxBFAxLKu = 7; BTxBAxBBxLKu = 8;
  13.         RTxDxRA = 9; RSxDxRA = 11; RSxRAxRBxRcu = 12; RTxRAxNBxRcu = 13; RSxRAxNBxRcu = 14;
  14.         RTxRAxUI = 15; RTxRAxSI = 16; RTxRAxRBxRc = 17; RTxRAxRBxRcu = 18; RTxRAxRc = 19; RTxRAxRcu = 20; 
  15.         BFxRAxSI = 21; BFxRAxUI = 22; BFxRAxRBxRcu = 23; TOxRAxSI = 24; TOxRAxRBxRcu = 25; RAxRSxUI = 26; 
  16.         RAxRSxRBxRc = 27; RAxRSxRc = 28; RAxRSxSHxMBxMExRc = 29; RAxRSxRBxMBxMExRc = 30; RAxRSxSHxRc = 31;
  17.         SPRxRSxRcu = 32; RTxSPRxRcu = 33; FXMxRSxRcu = 34; BFxRcu = 35; RTxRcu = 36; RSxRcu = 37; FRTxDxRA = 38;
  18.         FRTxRAxRBxRcu = 39; FRSxDxRA = 40; FRSxRAxRBxRcu = 41; FRTxFRBxRc = 42; FRTxFRAxFRBxRc = 43;
  19.         FRTxFRAxFRCxRc = 44; FRTxFRAxFRCxFRBxRc = 45; BFxFRAxFRBxRcu = 46; FRTxRc = 47; BFxBFAxRcu = 48;
  20.         FLMxFRBxRc = 49; BFxIxRc = 50; BTxRc = 51; RAxRBxRc = 52; RAxRBxRcu = 53; SRxRSxRcu = 54; RTxSRxRcu = 55;
  21.         RTxRA = 56; RTxSI = 57;
  22.         (* misc *)
  23.         tab = 9X;
  24.         Pointer = 13; ProcTyp = 14;
  25.         W: Texts.Writer;
  26.         curInstr, pc: LONGINT;
  27.     PROCEDURE ReadInt (VAR r: Files.Rider; VAR x: INTEGER);
  28.         VAR a: ARRAY 2 OF CHAR; i: INTEGER;
  29.     BEGIN
  30.         FOR i := 0 TO 1 DO Files.Read(r, a[i]) END;
  31.         x := SYSTEM.VAL(INTEGER, a);
  32.     END ReadInt;
  33.     PROCEDURE ReadLInt (VAR r: Files.Rider; VAR x: LONGINT);
  34.         VAR a: ARRAY 4 OF CHAR; i: INTEGER;
  35.     BEGIN
  36.         FOR i := 0 TO 3  DO Files.Read(r, a[i]) END;
  37.         x := SYSTEM.VAL(LONGINT, a);
  38.     END ReadLInt;
  39.     PROCEDURE Instr (mnemonic: ARRAY OF CHAR; fields: SHORTINT);
  40.         PROCEDURE WriteCB (i: LONGINT);
  41.         BEGIN
  42.             Texts.WriteString(W, "CF"); Texts.WriteInt(W, i DIV 4, 0); 
  43.             CASE i MOD 4 OF 
  44.                 0: Texts.WriteString(W, ".LT")
  45.             |  1: Texts.WriteString(W, ".GT")
  46.             |  2: Texts.WriteString(W, ".EQ")
  47.             |  3: Texts.WriteString(W, ".SO")
  48.             END
  49.         END WriteCB;
  50.         PROCEDURE AA;
  51.         BEGIN IF 30 IN SYSTEM.VAL(SET, curInstr) THEN Texts.Write(W, "a") END
  52.         END AA;
  53.         PROCEDURE BA;
  54.         BEGIN WriteCB(curInstr DIV 65536 MOD 32)
  55.         END BA;
  56.         PROCEDURE BB;
  57.         BEGIN WriteCB(curInstr DIV 2048 MOD 32)
  58.         END BB;
  59.         PROCEDURE BD;
  60.         BEGIN Texts.WriteHex(W, ASH(SYSTEM.LSH(curInstr MOD 65536 DIV 4, 18), -16)+pc); Texts.Write(W, "H")
  61.         END BD;
  62.         PROCEDURE BF;
  63.         BEGIN Texts.WriteString(W, "CF"); Texts.WriteInt(W, curInstr DIV 8388608 MOD 8, 0)
  64.         END BF;
  65.         PROCEDURE BFA;
  66.         BEGIN Texts.WriteString(W, "CF"); Texts.WriteInt(W, curInstr DIV 262144 MOD 8, 0)
  67.         END BFA;
  68.         PROCEDURE BI;
  69.         BEGIN WriteCB(curInstr DIV 65536 MOD 32)
  70.         END BI;
  71.         PROCEDURE BO;
  72.         BEGIN
  73.             CASE curInstr DIV 2097152 MOD 32 OF
  74.                 0, 1: Texts.WriteString(W, "(--CTR#0)&~CB")
  75.             |  2, 3: Texts.WriteString(W, "(--CTR=0)&~CB")
  76.             |  4..7: Texts.WriteString(W, "~CB")
  77.             |  8, 9: Texts.WriteString(W, "(--CTR#0)&~CB")
  78.             |  10, 11: Texts.WriteString(W, "(--CTR=0)&~CB")
  79.             |  12..15: Texts.WriteString(W, "CB")
  80.             |  16, 17, 24, 25: Texts.WriteString(W, "--CTR#0")
  81.             |  18, 19, 26, 27: Texts.WriteString(W, "--CTR=0")
  82.             |  20..23, 28..31: Texts.WriteString(W, "ALWAYS")
  83.             END
  84.         END BO;
  85.         PROCEDURE BT;
  86.         BEGIN WriteCB(curInstr DIV 2097152 MOD 32)
  87.         END BT;
  88.         PROCEDURE D;
  89.         BEGIN Texts.WriteInt(W, ASH(SYSTEM.LSH(curInstr MOD 65536, 16), -16), 0)
  90.         END D;
  91.         PROCEDURE FXM;
  92.             VAR s: SET; i: INTEGER; first: BOOLEAN;
  93.         BEGIN s := SYSTEM.VAL(SET, curInstr DIV 4096 MOD 256); first := TRUE; i := 24; Texts.WriteString(W, "CF[");
  94.             WHILE i < 32 DO
  95.                 IF i IN s THEN
  96.                     IF ~first THEN Texts.Write(W, ",") ELSE first := FALSE END; 
  97.                     Texts.WriteInt(W, i-24, 0)
  98.                 END;
  99.                 INC(i)
  100.             END;
  101.             Texts.Write(W, "]")
  102.         END FXM;
  103.         PROCEDURE FLM;        
  104.             VAR s: SET; i: INTEGER; first: BOOLEAN;
  105.         BEGIN s := SYSTEM.VAL(SET, curInstr DIV 131072 MOD 256); first := TRUE; i := 24; Texts.WriteString(W, "FPSCR[");
  106.             WHILE i < 32 DO
  107.                 IF i IN s THEN
  108.                     IF ~first THEN Texts.Write(W, ",") ELSE first := FALSE END; 
  109.                     Texts.WriteInt(W, i-24, 0)
  110.                 END;
  111.                 INC(i)
  112.             END;
  113.             Texts.Write(W, "]")
  114.         END FLM;
  115.         PROCEDURE FRA;
  116.         BEGIN Texts.Write(W, "F"); Texts.WriteInt(W, curInstr DIV 65536 MOD 32, 0)
  117.         END FRA;
  118.         PROCEDURE FRB;
  119.         BEGIN Texts.Write(W, "F"); Texts.WriteInt(W, curInstr DIV 2048 MOD 32, 0)
  120.         END FRB;
  121.         PROCEDURE FRC;
  122.         BEGIN Texts.Write(W, "F"); Texts.WriteInt(W, curInstr DIV 64 MOD 32, 0)
  123.         END FRC;
  124.         PROCEDURE FRS;
  125.         BEGIN Texts.Write(W, "F"); Texts.WriteInt(W, curInstr DIV 2097152 MOD 32, 0)
  126.         END FRS;
  127.         PROCEDURE FRT;
  128.         BEGIN Texts.Write(W, "F"); Texts.WriteInt(W, curInstr DIV 2097152 MOD 32, 0)
  129.         END FRT;
  130.         PROCEDURE I;
  131.             VAR s: SET; i: INTEGER;
  132.         BEGIN
  133.             s := SYSTEM.VAL(SET, curInstr DIV 4096 MOD 16); i := 28;
  134.             WHILE i < 32 DO 
  135.                 IF i IN s THEN Texts.Write(W, "1") ELSE Texts.Write(W, "0") END; 
  136.                 INC(i) 
  137.             END;
  138.             Texts.Write(W, "B")
  139.         END I;
  140.         PROCEDURE LI;
  141.         BEGIN
  142.             Texts.WriteHex(W, pc+ASH(SYSTEM.LSH(curInstr MOD 67108864 DIV 4, 8), -6)); Texts.Write(W, "H");
  143.             Texts.WriteString(W, " ["); Texts.WriteHex(W, -ASH(SYSTEM.LSH(curInstr MOD 67108864 DIV 4, 8), -6));
  144.             Texts.WriteString(W, "H]")
  145.         END LI;
  146.         PROCEDURE LK;
  147.         BEGIN IF curInstr MOD 2 = 1 THEN Texts.Write(W, "l") END
  148.         END LK;
  149.         PROCEDURE LKU;
  150.         BEGIN IF curInstr MOD 2 = 1 THEN Texts.Write(W, 9X); Texts.WriteString(W, "# invalidate LR") END
  151.         END LKU;
  152.         PROCEDURE MB;
  153.         BEGIN Texts.WriteInt(W, curInstr DIV 64 MOD 32, 0)
  154.         END MB;
  155.         PROCEDURE ME;
  156.         BEGIN Texts.WriteInt(W, curInstr DIV 2 MOD 32, 0)
  157.         END ME;
  158.         PROCEDURE NB;
  159.         BEGIN Texts.WriteInt(W, curInstr DIV 2048 MOD 32, 0)
  160.         END NB;
  161.         PROCEDURE OE;
  162.         BEGIN IF 21 IN SYSTEM.VAL(SET, curInstr) THEN Texts.Write(W, "o") END
  163.         END OE;
  164.         PROCEDURE RA;
  165.         BEGIN Texts.Write(W, "R"); Texts.WriteInt(W, curInstr DIV 65536 MOD 32, 0)
  166.         END RA;
  167.         PROCEDURE RB;
  168.         BEGIN Texts.Write(W, "R"); Texts.WriteInt(W, curInstr DIV 2048 MOD 32, 0)
  169.         END RB;
  170.         PROCEDURE RC;
  171.         BEGIN IF curInstr MOD 2 = 1 THEN Texts.Write(W, ".") END
  172.         END RC;
  173.         PROCEDURE RCU;
  174.         BEGIN IF curInstr MOD 2 = 1 THEN Texts.Write(W, 9X); Texts.WriteString(W, "# invalidate CR") END
  175.         END RCU;
  176.         PROCEDURE RS;
  177.         BEGIN Texts.Write(W, "R"); Texts.WriteInt(W, curInstr DIV 2097152 MOD 32, 0)
  178.         END RS;
  179.         PROCEDURE RT;
  180.         BEGIN Texts.Write(W, "R"); Texts.WriteInt(W, curInstr DIV 2097152 MOD 32, 0)
  181.         END RT;
  182.         PROCEDURE SH;
  183.         BEGIN Texts.WriteInt(W, curInstr DIV 2048 MOD 32, 0)
  184.         END SH;
  185.         PROCEDURE SI;
  186.         BEGIN Texts.WriteInt(W, ASH(SYSTEM.LSH(curInstr, 16), -16), 0)
  187.         END SI;
  188.         PROCEDURE SPR;
  189.         BEGIN
  190.             CASE curInstr DIV 65536 MOD 32 OF
  191.                 0: Texts.WriteString(W, "MQ")
  192.             |  1: Texts.WriteString(W, "XER")
  193.             |  4: Texts.WriteString(W, "to RTCU")
  194.             |  5: Texts.WriteString(W, "to RTCL")
  195.             |  6: Texts.WriteString(W, "to DEC")
  196.             |  8: Texts.WriteString(W, "LR")
  197.             |  9: Texts.WriteString(W, "CTR")
  198.             |  17: Texts.WriteString(W, "TID")
  199.             |  18: Texts.WriteString(W, "DSISR")
  200.             |  19: Texts.WriteString(W, "DAR")
  201.             |  20: Texts.WriteString(W, "to RTCU")
  202.             |  21: Texts.WriteString(W, "to RTCL")
  203.             |  22: Texts.WriteString(W, "to DEC")
  204.             |  24: Texts.WriteString(W, "SDR0")
  205.             |  25: Texts.WriteString(W, "SDR1")
  206.             |  26: Texts.WriteString(W, "SRR0")
  207.             |  27: Texts.WriteString(W, "SRR1")
  208.             |  2, 3, 7, 10..16, 23, 28..31: Texts.WriteString(W, "INVALID")
  209.             END
  210.         END SPR;
  211.         PROCEDURE SR;
  212.         BEGIN Texts.Write(W, "S"); Texts.WriteInt(W, curInstr DIV 65536 MOD 16, 0)
  213.         END SR;
  214.         PROCEDURE TOf;
  215.         BEGIN
  216.             CASE curInstr DIV 2097152 MOD 32 OF
  217.                 0: Texts.WriteString(W, "NEVER")
  218.             |  1: Texts.WriteString(W, ">u")
  219.             |  2: Texts.WriteString(W, "<u")
  220.             |  3, 11, 19, 24, 25, 26, 27: Texts.Write(W, "#")
  221.             |  4: Texts.Write(W, "=")
  222.             |  5: Texts.WriteString(W, ">=u")
  223.             |  6: Texts.WriteString(W, "<=u")
  224.             |  7, 15, 23, 28, 29, 30, 31: Texts.WriteString(W, "ALWAYS")
  225.             |  8: Texts.WriteString(W, ">s")
  226.             |  9: Texts.WriteString(W, ">s OR >u")
  227.             |  10: Texts.WriteString(W, ">s OR <u")
  228.             |  12: Texts.WriteString(W, ">=s")
  229.             |  13: Texts.WriteString(W, ">=s OR >u")
  230.             |  14: Texts.WriteString(W, ">=s OR <u")
  231.             |  16: Texts.WriteString(W, "<s")
  232.             |  17: Texts.WriteString(W, "<s OR >u")
  233.             |  18: Texts.WriteString(W, "<s OR <u")
  234.             |  20: Texts.WriteString(W, "<=s")
  235.             |  21: Texts.WriteString(W, "<=s OR >u")
  236.             |  22: Texts.WriteString(W, "<=s OR <u")
  237.             END
  238.         END TOf;
  239.         PROCEDURE UI;
  240.         BEGIN Texts.WriteHex(W, curInstr MOD 65536); Texts.Write(W, "H")
  241.         END UI;
  242.         PROCEDURE tab;
  243.         BEGIN Texts.Write(W, 9X)
  244.         END tab;
  245.         PROCEDURE comma;
  246.         BEGIN Texts.WriteString(W, ", ")
  247.         END comma;
  248.         PROCEDURE op;
  249.         BEGIN Texts.Write(W, "(")
  250.         END op;
  251.         PROCEDURE cp;
  252.         BEGIN Texts.Write(W, ")")
  253.         END cp;
  254.     BEGIN
  255.         Texts.WriteString(W, mnemonic);
  256.         CASE fields OF
  257.             LIxAAxLK: LK; AA; tab; LI
  258.         |  BOxBIxBDxAAxLK: LK; AA; tab; BO; comma; BI; comma; BD
  259.         |  BOxBIxLK: LK; tab; BO; comma; BI
  260.         |  LKu: tab; LKU
  261.         |  Rcu: tab; LKU
  262.         |  None:
  263.         |  BFxBFAxLKu: tab; BF; comma; BFA; LKU
  264.         |  BTxBAxBBxLKu: tab; BT; comma; BA; comma; BB; LKU
  265.         |  RTxDxRA: tab; RT; comma; D; op; RA; cp
  266.         |  RSxDxRA: tab; RS; comma; D; op; RA; cp
  267.         |  RSxRAxRBxRcu: tab; RS; comma; RA; comma; RB; RCU
  268.         |  RTxRAxNBxRcu: tab; RT; comma; RA; comma; NB; RCU
  269.         |  RSxRAxNBxRcu: tab; RS; comma; RA; comma; NB; RCU
  270.         |  RTxRAxUI: tab; RT; comma; RA; comma; UI
  271.         |  RTxRAxSI: tab; RT; comma; RA; comma; SI
  272.         |  RTxRAxRBxRc: RC; tab; RT; comma; RA; comma; RB
  273.         |  RTxRAxRBxRcu: tab; RT; comma; RA; comma; RB; RCU
  274.         |  RTxRAxRc: RC; tab; RT; comma; RA
  275.         |  RTxRAxRcu: tab; RT; comma; RA; RCU
  276.         |  BFxRAxSI: tab; BF; comma; RA; comma; SI
  277.         |  BFxRAxUI: tab; BF; comma; RA; comma; UI
  278.         |  BFxRAxRBxRcu: tab; BF; comma; RA; comma; RB; RCU
  279.         |  TOxRAxSI: tab; TOf; comma; RA; comma; SI
  280.         |  TOxRAxRBxRcu: tab; TOf; comma; RA; comma; RB; RCU
  281.         |  RAxRSxUI: tab; RA; comma; RS; comma; UI
  282.         |  RAxRSxRBxRc: RC; tab; RA; comma; RS; comma; RB
  283.         |  RAxRSxRc: RC; tab; RA; comma; RS
  284.         |  RAxRSxSHxMBxMExRc: RC; tab; RA; comma; RS; comma; SH; comma; MB; comma; ME
  285.         |  RAxRSxRBxMBxMExRc: RC; tab; RA; comma; RS; comma; RB; comma; MB; comma; ME
  286.         |  RAxRSxSHxRc: RC; tab; RA; comma; RS; comma; SH
  287.         |  SPRxRSxRcu: tab; SPR; comma; RS; RCU
  288.         |  RTxSPRxRcu: tab; RT; comma; SPR; RCU
  289.         |  FXMxRSxRcu: tab; FXM; comma; RS; RCU
  290.         |  BFxRcu: tab; BF; RCU
  291.         |  RTxRcu: tab; RT; RCU
  292.         |  RSxRcu: tab; RS; RCU
  293.         |  FRTxDxRA: tab; FRT; comma; D; op; RA; cp
  294.         |  FRTxRAxRBxRcu: tab; FRT; comma; RA; comma; RB; RCU
  295.         |  FRSxDxRA: tab; FRS; comma; D; op; RA; cp
  296.         |  FRSxRAxRBxRcu: tab; FRS; comma; RA; comma; RB; RCU
  297.         |  FRTxFRBxRc: RC; tab; FRT; comma; FRB
  298.         |  FRTxFRAxFRBxRc: RC; tab; FRT; comma; FRA; comma; FRB
  299.         |  FRTxFRAxFRCxRc: RC; tab; FRT; comma; FRA; comma; FRC
  300.         |  FRTxFRAxFRCxFRBxRc: RC; tab; FRT; comma; FRA; comma; FRC; comma; FRB
  301.         |  BFxFRAxFRBxRcu: tab; BF; comma; FRA; comma; FRB; RCU
  302.         |  FRTxRc: RC; tab; FRT
  303.         |  BFxBFAxRcu: tab; BF; comma; BFA; RCU
  304.         |  FLMxFRBxRc: RC; tab; FLM; comma; FRB
  305.         |  BFxIxRc: RC; tab; BF; comma; I
  306.         |  BTxRc: RC; tab; BT
  307.         |  RAxRBxRc: RC; tab; RA; comma; RB
  308.         |  RAxRBxRcu: tab; RA; comma; RB; RCU
  309.         |  SRxRSxRcu: tab; SR; comma; RS; RCU
  310.         |  RTxSRxRcu: tab; RT; comma; SR; RCU
  311.         |  RTxRA: tab; RT; comma; RA
  312.         |  RTxSI: tab; RT; comma; SI
  313.         END;
  314.     END Instr;
  315.     PROCEDURE error;
  316.     BEGIN Texts.WriteString(W, "invalid instruction "); Texts.WriteHex(W, curInstr); Texts.Write(W, "H"); Texts.WriteLn(W)
  317.     END error;
  318.     PROCEDURE DecodeXL (instr: LONGINT);
  319.         VAR extOp: LONGINT;
  320.     BEGIN
  321.         extOp := ASH(instr MOD 2048, -1);
  322.         IF extOp <= 150 THEN
  323.             IF extOp <= 50 THEN
  324.                 IF extOp <= 16 THEN
  325.                     IF extOp = 0 THEN Instr("mcrf", BFxBFAxLKu) ELSIF extOp = 16 THEN Instr("bclr", BOxBIxLK) 
  326.                     ELSE error END
  327.                 ELSE
  328.                     IF extOp = 33 THEN Instr("crnor", BTxBAxBBxLKu) ELSIF extOp = 50 THEN Instr("rfi", LKu) 
  329.                     ELSE error END
  330.                 END
  331.             ELSE
  332.                 IF extOp <= 129 THEN
  333.                     IF extOp = 82 THEN Instr("rfsvc", LKu) ELSIF extOp = 129 THEN Instr("crandc", BTxBAxBBxLKu) 
  334.                     ELSE error END
  335.                 ELSE
  336.                     IF extOp = 150 THEN Instr("isync", LKu) ELSE error END
  337.                 END
  338.             END
  339.         ELSE
  340.             IF extOp <= 289 THEN
  341.                 IF extOp <= 225 THEN
  342.                     IF extOp = 193 THEN Instr("crxor", BTxBAxBBxLKu) ELSIF extOp = 225 THEN Instr("crnand", BTxBAxBBxLKu) 
  343.                     ELSE error END
  344.                 ELSE
  345.                     IF extOp = 257 THEN Instr("crand", BTxBAxBBxLKu) ELSIF extOp = 289 THEN Instr("creqv", BTxBAxBBxLKu) 
  346.                     ELSE error END
  347.                 END
  348.             ELSE
  349.                 IF extOp <= 449 THEN
  350.                     IF extOp = 417 THEN Instr("crorc", BTxBAxBBxLKu) ELSIF extOp = 449 THEN Instr("cror", BTxBAxBBxLKu) 
  351.                     ELSE error END
  352.                 ELSE
  353.                     IF extOp = 528 THEN Instr("bcctr", BOxBIxLK) ELSE error END
  354.                 END
  355.             END
  356.         END
  357.     END DecodeXL;
  358.     PROCEDURE DecodeX (instr: LONGINT);
  359.         VAR extOp: LONGINT; s: ARRAY 2 OF CHAR;
  360.     BEGIN
  361.         extOp := ASH(instr MOD 2048, -1);
  362.         IF extOp <= 467 THEN
  363.             IF extOp <= 200 THEN
  364.                 IF extOp <= 87 THEN
  365.                     IF extOp <= 26 THEN
  366.                         IF extOp <= 10 THEN
  367.                             IF extOp <= 4 THEN
  368.                                 IF extOp = 0 THEN Instr("cmp", BFxRAxRBxRcu) 
  369.                                 ELSIF extOp = 4 THEN Instr("tw", TOxRAxRBxRcu) 
  370.                                 ELSE error END
  371.                             ELSE
  372.                                 IF extOp = 8 THEN Instr("subfc", RTxRAxRBxRc) 
  373.                                 ELSIF extOp = 10 THEN Instr("addc", RTxRAxRBxRc) 
  374.                                 ELSE error END
  375.                             END
  376.                         ELSE
  377.                             IF extOp <= 23 THEN
  378.                                 IF extOp = 19 THEN Instr("mfcr", RTxRcu) ELSIF extOp = 23 THEN Instr("lwzx", RTxRAxRBxRcu) 
  379.                                 ELSE error END
  380.                             ELSE
  381.                                 IF extOp = 24 THEN Instr("slw", RAxRSxRBxRc) ELSIF extOp = 26 THEN Instr("cntlzw", RAxRSxRc) 
  382.                                 ELSE error END
  383.                             END
  384.                         END
  385.                     ELSE
  386.                         IF extOp <= 55 THEN
  387.                             IF extOp <= 29 THEN
  388.                                 IF extOp = 28 THEN Instr("and", RAxRSxRBxRc) 
  389.                                 ELSIF extOp = 29 THEN Instr("maskg", RAxRSxRBxRc) 
  390.                                 ELSE error END
  391.                             ELSE
  392.                                 IF extOp = 32 THEN Instr("cmpl", BFxRAxRBxRcu) ELSIF extOp = 55 THEN Instr("lwzux", RTxRAxRBxRcu) 
  393.                                 ELSE error END
  394.                             END
  395.                         ELSE
  396.                             IF extOp <= 83 THEN
  397.                                 IF extOp = 60 THEN Instr("andc", RAxRSxRBxRc) ELSIF extOp = 83 THEN Instr("mfmsr", RTxRcu) 
  398.                                 ELSE error END
  399.                             ELSE
  400.                                 IF extOp = 87 THEN Instr("lbzx", RTxRAxRBxRcu) ELSE error END
  401.                             END
  402.                         END
  403.                     END
  404.                 ELSE
  405.                     IF extOp <= 144 THEN
  406.                         IF extOp <= 119 THEN
  407.                             IF extOp <= 107 THEN
  408.                                 IF extOp = 104 THEN Instr("neg", RTxRAxRc) ELSIF extOp = 107 THEN Instr("mul", RTxRAxRBxRc) 
  409.                                 ELSE error END
  410.                             ELSE
  411.                                 IF extOp = 118 THEN Instr("clf", RAxRBxRcu) ELSIF extOp = 119 THEN Instr("lbzux", RTxRAxRBxRcu) 
  412.                                 ELSE error END
  413.                             END
  414.                         ELSE
  415.                             IF extOp <= 136 THEN
  416.                                 IF extOp = 124 THEN Instr("nor", RAxRSxRBxRc) ELSIF extOp = 136 THEN Instr("subfe", RTxRAxRBxRc) 
  417.                                 ELSE error END
  418.                             ELSE
  419.                                 IF extOp = 138 THEN Instr("adde", RTxRAxRBxRc) ELSIF extOp = 144 THEN Instr("mtcrf", FXMxRSxRcu) 
  420.                                 ELSE error END
  421.                             END
  422.                         END
  423.                     ELSE
  424.                         IF extOp <= 153 THEN
  425.                             IF extOp <= 151 THEN
  426.                                 IF extOp = 146 THEN Instr("mtmsr", RSxRcu) ELSIF extOp = 151 THEN Instr("stwx", RSxRAxRBxRcu) 
  427.                                 ELSE error END
  428.                             ELSE
  429.                                 IF extOp = 152 THEN Instr("slq", RAxRSxRBxRc) ELSIF extOp = 153 THEN Instr("sle", RAxRSxRBxRc) 
  430.                                 ELSE error END
  431.                             END
  432.                         ELSE
  433.                             IF extOp <= 184 THEN
  434.                                 IF extOp = 183 THEN Instr("stwux", RSxRAxRBxRcu) 
  435.                                 ELSIF extOp = 184 THEN Instr("sliq", RAxRSxSHxRc) 
  436.                                 ELSE error END
  437.                             ELSE
  438.                                 IF extOp = 200 THEN Instr("subfze", RTxRAxRc) ELSE error END
  439.                             END
  440.                         END
  441.                     END
  442.                 END
  443.             ELSE
  444.                 IF extOp <= 279 THEN
  445.                     IF extOp <= 235 THEN
  446.                         IF extOp <= 216 THEN
  447.                             IF extOp <= 210 THEN
  448.                                 IF extOp = 202 THEN Instr("addze", RTxRAxRc) ELSIF extOp = 210 THEN Instr("mtsr", SRxRSxRcu) 
  449.                                 ELSE error END
  450.                             ELSE
  451.                                 IF extOp = 215 THEN Instr("stbx", RSxRAxRBxRcu) 
  452.                                 ELSIF extOp = 216 THEN Instr("sllq", RAxRSxRBxRc) 
  453.                                 ELSE error END
  454.                             END
  455.                         ELSE
  456.                             IF extOp <= 232 THEN
  457.                                 IF extOp = 217 THEN Instr("sleq", RAxRSxRBxRc) ELSIF extOp = 232 THEN Instr("subfme", RTxRAxRc) 
  458.                                 ELSE error END
  459.                             ELSE
  460.                                 IF extOp = 234 THEN Instr("addme", RTxRAxRc) ELSIF extOp = 235 THEN Instr("mullw", RTxRAxRBxRc) 
  461.                                 ELSE error END
  462.                             END
  463.                         END
  464.                     ELSE
  465.                         IF extOp <= 264 THEN
  466.                             IF extOp <= 247 THEN
  467.                                 IF extOp = 242 THEN Instr("mtsrin", RSxRAxRBxRcu) 
  468.                                 ELSIF extOp = 247 THEN Instr("stbux", RSxRAxRBxRcu) 
  469.                                 ELSE error END
  470.                             ELSE
  471.                                 IF extOp = 248 THEN Instr("slliq", RAxRSxSHxRc) 
  472.                                 ELSIF extOp = 264 THEN Instr("doz", RTxRAxRBxRc) 
  473.                                 ELSE error END
  474.                             END
  475.                         ELSE
  476.                             IF extOp <= 277 THEN
  477.                                 IF extOp = 266 THEN Instr("add", RTxRAxRBxRc) 
  478.                                 ELSIF extOp = 277 THEN Instr("lscbx", RTxRAxRBxRc) 
  479.                                 ELSE error END
  480.                             ELSE
  481.                                 IF extOp = 279 THEN Instr("lhzx", RTxRAxRBxRcu) ELSE error END
  482.                             END
  483.                         END
  484.                     END
  485.                 ELSE
  486.                     IF extOp <= 360 THEN
  487.                         IF extOp <= 316 THEN
  488.                             IF extOp <= 306 THEN
  489.                                 IF extOp = 284 THEN Instr("eqv", RAxRSxRBxRc) ELSIF extOp = 306 THEN Instr("tlbie", RAxRBxRc) 
  490.                                 ELSE error END
  491.                             ELSE
  492.                                 IF extOp = 311 THEN Instr("lhzux", RTxRAxRBxRcu) 
  493.                                 ELSIF extOp = 316 THEN Instr("xor", RAxRSxRBxRc) 
  494.                                 ELSE error END
  495.                             END
  496.                         ELSE
  497.                             IF extOp <= 339 THEN
  498.                                 IF extOp = 331 THEN Instr("div", RTxRAxRBxRc) ELSIF extOp = 339 THEN Instr("mfspr", RTxSPRxRcu) 
  499.                                 ELSE error END
  500.                             ELSE
  501.                                 IF extOp = 343 THEN Instr("lhax", RTxRAxRBxRcu) ELSIF extOp = 360 THEN Instr("abs", RTxRAxRc) 
  502.                                 ELSE error END
  503.                             END
  504.                         END
  505.                     ELSE
  506.                         IF extOp <= 412 THEN
  507.                             IF extOp <= 375 THEN
  508.                                 IF extOp = 363 THEN Instr("divs", RTxRAxRBxRc) 
  509.                                 ELSIF extOp = 375 THEN Instr("lhaux", RTxRAxRBxRcu) 
  510.                                 ELSE error END
  511.                             ELSE
  512.                                 IF extOp = 407 THEN Instr("sthx", RSxRAxRBxRcu) 
  513.                                 ELSIF extOp = 412 THEN Instr("orc", RAxRSxRBxRc) 
  514.                                 ELSE error END
  515.                             END
  516.                         ELSE
  517.                             IF extOp <= 444 THEN
  518.                                 IF extOp = 439 THEN Instr("sthux", RSxRAxRBxRcu) 
  519.                                 ELSIF extOp = 444 THEN Instr("or", RAxRSxRBxRc) 
  520.                                 ELSE error END
  521.                             ELSE
  522.                                 IF extOp = 467 THEN Instr("mtspr", SPRxRSxRcu) ELSE error END
  523.                             END
  524.                         END
  525.                     END
  526.                 END
  527.             END
  528.         ELSE
  529.             IF extOp <= 665 THEN
  530.                 IF extOp <= 595 THEN
  531.                     IF extOp <= 533 THEN
  532.                         IF extOp <= 512 THEN
  533.                             IF extOp <= 488 THEN
  534.                                 IF extOp = 476 THEN Instr("nand", RAxRSxRBxRc) ELSIF extOp = 488 THEN Instr("nabs", RTxRAxRc) 
  535.                                 ELSE error END
  536.                             ELSE
  537.                                 IF extOp = 502 THEN Instr("cli", RAxRBxRcu) ELSIF extOp = 512 THEN Instr("mcrxr", BFxRcu) 
  538.                                 ELSE error END
  539.                             END
  540.                         ELSE
  541.                             IF extOp <= 522 THEN
  542.                                 IF extOp = 520 THEN Instr("subfco", RTxRAxRBxRc) ELSIF extOp = 522 THEN Instr("addco", RTxRAxRBxRc) 
  543.                                 ELSE error END
  544.                             ELSE
  545.                                 IF extOp = 531 THEN Instr("clcs", RTxRAxRcu) ELSIF extOp = 533 THEN Instr("lswx", RTxRAxRBxRcu) 
  546.                                 ELSE error END
  547.                             END
  548.                         END
  549.                     ELSE
  550.                         IF extOp <= 537 THEN
  551.                             IF extOp <= 535 THEN
  552.                                 IF extOp = 534 THEN Instr("lwbrx", RTxRAxRBxRcu) 
  553.                                 ELSIF extOp = 535 THEN Instr("lfsx", FRTxRAxRBxRcu) 
  554.                                 ELSE error END
  555.                             ELSE
  556.                                 IF extOp = 536 THEN Instr("srw", RAxRSxRBxRc) ELSIF extOp = 537 THEN Instr("rrib", RAxRSxRBxRc) 
  557.                                 ELSE error END
  558.                             END
  559.                         ELSE
  560.                             IF extOp <= 567 THEN
  561.                                 IF extOp = 541 THEN Instr("maskir", RAxRSxRBxRc) 
  562.                                 ELSIF extOp = 567 THEN Instr("lfsux", FRTxRAxRBxRcu) 
  563.                                 ELSE error END
  564.                             ELSE
  565.                                 IF extOp = 595 THEN Instr("mfsr", RTxSRxRcu) ELSE error END
  566.                             END
  567.                         END
  568.                     END
  569.                 ELSE
  570.                     IF extOp <= 631 THEN
  571.                         IF extOp <= 616 THEN
  572.                             IF extOp <= 598 THEN
  573.                                 IF extOp = 597 THEN Instr("lswi", RTxRAxNBxRcu) ELSIF extOp = 598 THEN Instr("sync", Rcu) 
  574.                                 ELSE error END
  575.                             ELSE
  576.                                 IF extOp = 599 THEN Instr("lfdx", FRTxRAxRBxRcu) 
  577.                                 ELSIF extOp = 616 THEN Instr("nego", RTxRAxRc) 
  578.                                 ELSE error END
  579.                             END
  580.                         ELSE
  581.                             IF extOp <= 627 THEN
  582.                                 IF extOp = 619 THEN Instr("mulo", RTxRAxRBxRc) 
  583.                                 ELSIF extOp = 627 THEN Instr("mfsri", RTxRAxRBxRcu) 
  584.                                 ELSE error END
  585.                             ELSE
  586.                                 IF extOp = 630 THEN Instr("dclst", RAxRBxRcu) 
  587.                                 ELSIF extOp = 631 THEN Instr("lfdux", FRTxRAxRBxRcu) 
  588.                                 ELSE error END
  589.                             END
  590.                         END
  591.                     ELSE
  592.                         IF extOp <= 662 THEN
  593.                             IF extOp <= 650 THEN
  594.                                 IF extOp = 648 THEN Instr("subfeo", RTxRAxRBxRc) 
  595.                                 ELSIF extOp = 650 THEN Instr("addeo", RTxRAxRBxRc) 
  596.                                 ELSE error END
  597.                             ELSE
  598.                                 IF extOp = 661 THEN Instr("stswx", RSxRAxRBxRcu) 
  599.                                 ELSIF extOp = 662 THEN Instr("stwbrx", RSxRAxRBxRcu) 
  600.                                 ELSE error END
  601.                             END
  602.                         ELSE
  603.                             IF extOp <= 664 THEN
  604.                                 IF extOp = 663 THEN Instr("stfsx", FRSxRAxRBxRcu) 
  605.                                 ELSIF extOp = 664 THEN Instr("srq", RAxRSxRBxRc) 
  606.                                 ELSE error END
  607.                             ELSE
  608.                                 IF extOp = 665 THEN Instr("sre", RAxRSxRBxRc) ELSE error END
  609.                             END
  610.                         END
  611.                     END
  612.                 END
  613.             ELSE
  614.                 IF extOp <= 778 THEN
  615.                     IF extOp <= 729 THEN
  616.                         IF extOp <= 714 THEN
  617.                             IF extOp <= 696 THEN
  618.                                 IF extOp = 695 THEN Instr("stfsux", FRSxRAxRBxRcu) 
  619.                                 ELSIF extOp = 696 THEN Instr("sriq", RAxRSxSHxRc) 
  620.                                 ELSE error END
  621.                             ELSE
  622.                                 IF extOp = 712 THEN Instr("subfzeo", RTxRAxRc) ELSIF extOp = 714 THEN Instr("addzeo", RTxRAxRc) 
  623.                                 ELSE error END
  624.                             END
  625.                         ELSE
  626.                             IF extOp <= 727 THEN
  627.                                 IF extOp = 725 THEN Instr("stswi", RSxRAxNBxRcu) 
  628.                                 ELSIF extOp = 727 THEN Instr("stfdx", FRSxRAxRBxRcu) 
  629.                                 ELSE error END
  630.                             ELSE
  631.                                 IF extOp = 728 THEN Instr("srlq", RAxRSxRBxRc) 
  632.                                 ELSIF extOp = 729 THEN Instr("sreq", RAxRSxRBxRc) 
  633.                                 ELSE error END
  634.                             END
  635.                         END
  636.                     ELSE
  637.                         IF extOp <= 759 THEN
  638.                             IF extOp <= 746 THEN
  639.                                 IF extOp = 744 THEN Instr("subfmeo", RTxRAxRc) ELSIF extOp = 746 THEN Instr("addmeo", RTxRAxRc) 
  640.                                 ELSE error END
  641.                             ELSE
  642.                                 IF extOp = 747 THEN Instr("mullwo", RTxRAxRBxRc) 
  643.                                 ELSIF extOp = 759 THEN Instr("stfdux", FRSxRAxRBxRcu) 
  644.                                 ELSE error END
  645.                             END
  646.                         ELSE
  647.                             IF extOp <= 776 THEN
  648.                                 IF extOp = 760 THEN Instr("srliq", RAxRSxSHxRc) 
  649.                                 ELSIF extOp = 776 THEN Instr("dozo", RTxRAxRBxRc) 
  650.                                 ELSE error END
  651.                             ELSE
  652.                                 IF extOp = 778 THEN Instr("addo", RTxRAxRBxRc) ELSE error END
  653.                             END
  654.                         END
  655.                     END
  656.                 ELSE
  657.                     IF extOp <= 875 THEN
  658.                         IF extOp <= 824 THEN
  659.                             IF extOp <= 792 THEN
  660.                                 IF extOp = 790 THEN Instr("lhbrx", RTxRAxRBxRcu) 
  661.                                 ELSIF extOp = 792 THEN Instr("sraw", RAxRSxRBxRc) 
  662.                                 ELSE error END
  663.                             ELSE
  664.                                 IF extOp = 818 THEN Instr("rac", RTxRAxRBxRc) ELSIF extOp = 824 THEN Instr("srawi", RAxRSxSHxRc) 
  665.                                 ELSE error END
  666.                             END
  667.                         ELSE
  668.                             IF extOp <= 872 THEN
  669.                                 IF extOp = 843 THEN Instr("divo", RTxRAxRBxRc) ELSIF extOp = 872 THEN Instr("abso", RTxRAxRc) 
  670.                                 ELSE error END
  671.                             ELSE
  672.                                 IF extOp = 875 THEN Instr("divso", RTxRAxRBxRc) ELSE error END
  673.                             END
  674.                         END
  675.                     ELSE
  676.                         IF extOp <= 921 THEN
  677.                             IF extOp <= 918 THEN
  678.                                 IF extOp = 900 THEN Instr("nabso", RTxRAxRc) 
  679.                                 ELSIF extOp = 918 THEN Instr("sthbrx", RSxRAxRBxRcu) 
  680.                                 ELSE error END
  681.                             ELSE
  682.                                 IF extOp = 920 THEN Instr("sraq", RAxRSxRBxRc) 
  683.                                 ELSIF extOp = 921 THEN Instr("srea", RAxRSxRBxRc) 
  684.                                 ELSE error END
  685.                             END
  686.                         ELSE
  687.                             IF extOp <= 952 THEN
  688.                                 IF extOp = 922 THEN Instr("extsh", RAxRSxRc) ELSIF extOp = 952 THEN Instr("sraiq", RAxRSxSHxRc) 
  689.                                 ELSE error END
  690.                             ELSE
  691.                                 IF extOp = 954 THEN Instr("extsb", RAxRSxRc) ELSIF extOp = 1014 THEN Instr("dcbz", RAxRBxRcu) ELSE error END
  692.                             END
  693.                         END
  694.                     END
  695.                 END
  696.             END
  697.         END
  698.     END DecodeX;
  699.     PROCEDURE DecodeX2 (instr: LONGINT);
  700.         VAR extOp: LONGINT;
  701.     BEGIN
  702.         extOp := ASH(instr MOD 128, -1);    (* for A-form instructions *)
  703.         IF (extOp < 32) & (extOp IN {18, 20, 21, 25, 28, 29, 30, 31}) THEN
  704.             CASE extOp OF
  705.                 18: Instr("fdiv", FRTxFRAxFRBxRc)
  706.             |  20: Instr("fsub", FRTxFRAxFRBxRc)
  707.             |  21: Instr("fadd", FRTxFRAxFRBxRc)
  708.             |  25: Instr("fmul", FRTxFRAxFRCxRc)
  709.             |  28: Instr("fmsub", FRTxFRAxFRCxFRBxRc)
  710.             |  29: Instr("fmadd", FRTxFRAxFRCxFRBxRc)
  711.             |  30: Instr("fnmsub", FRTxFRAxFRCxFRBxRc)
  712.             |  31: Instr("fnmadd", FRTxFRAxFRCxFRBxRc)
  713.             END
  714.         ELSE extOp := ASH(instr MOD 2048, -1);    (* for X-form instructions *)
  715.             IF extOp <= 70 THEN
  716.                 IF extOp <= 38 THEN
  717.                     IF extOp <= 12 THEN
  718.                         IF extOp = 0 THEN Instr("fcmpu", BFxFRAxFRBxRcu) ELSIF extOp = 12 THEN Instr("frsp", FRTxFRBxRc) 
  719.                         ELSE error END
  720.                     ELSE
  721.                         IF extOp = 32 THEN Instr("fcmpo", BFxFRAxFRBxRcu) ELSIF extOp = 38 THEN Instr("mtfsb1", BTxRc) 
  722.                         ELSE error END
  723.                     END
  724.                 ELSE
  725.                     IF extOp <= 64 THEN
  726.                         IF extOp = 40 THEN Instr("fneg", FRTxFRBxRc) ELSIF extOp = 64 THEN Instr("mcrfs", BFxBFAxRcu) 
  727.                         ELSE error END
  728.                     ELSE
  729.                         IF extOp = 70 THEN Instr("mtfsb0", BTxRc) ELSE error END
  730.                     END
  731.                 END
  732.             ELSE
  733.                 IF extOp <= 136 THEN
  734.                     IF extOp <= 134 THEN
  735.                         IF extOp = 72 THEN Instr("fmr", FRTxFRBxRc) ELSIF extOp = 134 THEN Instr("mtfsfi", BFxIxRc) 
  736.                         ELSE error END
  737.                     ELSE
  738.                         IF extOp = 136 THEN Instr("fnabs", FRTxFRBxRc) ELSE error END
  739.                     END
  740.                 ELSE
  741.                     IF extOp <= 583 THEN
  742.                         IF extOp = 264 THEN Instr("fabs", FRTxFRBxRc) ELSIF extOp = 583 THEN Instr("mffs", FRTxRc) 
  743.                         ELSE error END
  744.                     ELSE
  745.                         IF extOp = 711 THEN Instr("mtfsf", FLMxFRBxRc) ELSE error END
  746.                     END
  747.                 END
  748.             END
  749.         END
  750.     END DecodeX2;
  751.     PROCEDURE DecodeInstr (instr: LONGINT);
  752.         VAR pOpcode: LONGINT; s: ARRAY 2 OF CHAR;
  753.     BEGIN curInstr := instr;
  754.         pOpcode := SYSTEM.LSH(instr, -26);
  755.         CASE pOpcode OF
  756.             3: Instr("twi", TOxRAxSI)
  757.         |  7: Instr("mulli", RTxRAxSI)
  758.         |  8: Instr("subfic", RTxRAxSI)
  759.         |  9: Instr("dozi", RTxRAxSI)
  760.         |  10: Instr("cmpli", BFxRAxUI)
  761.         |  11: Instr("cmpi", BFxRAxSI)
  762.         |  12: Instr("addic", RTxRAxSI)
  763.         |  13: Instr("addic.", RTxRAxSI)
  764.         |  14:
  765.                 IF instr DIV 65536 MOD 32 = 0 THEN Instr("li", RTxSI)
  766.                 ELSIF instr MOD 65536 = 0 THEN Instr("lr", RTxRA)
  767.                 ELSE Instr("addi", RTxDxRA)
  768.                 END
  769.         |  15: Instr("addis", RTxRAxUI)
  770.         |  16: Instr("bc", BOxBIxBDxAAxLK)
  771.         |  17: Instr("svc", None)    (* special handling to be added later *)
  772.         |  18: s[0] := "b"; s[1] := 0X; Instr(s, LIxAAxLK)
  773.         |  19: DecodeXL(instr)
  774.         |  20: Instr("rlwimi", RAxRSxSHxMBxMExRc)
  775.         |  21: Instr("rlwinm", RAxRSxSHxMBxMExRc)
  776.         |  22: Instr("rlmi", RAxRSxSHxMBxMExRc)
  777.         |  23: Instr("rlwnm", RAxRSxRBxMBxMExRc)
  778.         |  24: Instr("ori", RAxRSxUI)
  779.         |  25: Instr("oris", RAxRSxUI)
  780.         |  26: Instr("xori", RAxRSxUI)
  781.         |  27: Instr("xoris", RAxRSxUI)
  782.         |  28: Instr("andi.", RAxRSxUI)
  783.         |  29: Instr("andis.", RAxRSxUI)
  784.         |  31: DecodeX(instr)
  785.         |  32: Instr("lwz", RTxDxRA)
  786.         |  33: Instr("lwzu", RTxDxRA)
  787.         |  34: Instr("lbz", RTxDxRA)
  788.         |  35: Instr("lbzu", RTxDxRA)
  789.         |  36: Instr("stw", RSxDxRA)
  790.         |  37: Instr("stwu", RSxDxRA)
  791.         |  38: Instr("stb", RSxDxRA)
  792.         |  39: Instr("stbu", RSxDxRA)
  793.         |  40: Instr("lhz", RTxDxRA)
  794.         |  41: Instr("lhzu", RTxDxRA)
  795.         |  42: Instr("lha", RTxDxRA)
  796.         |  43: Instr("lhau", RTxDxRA)
  797.         |  44: Instr("sth", RSxDxRA)
  798.         |  45: Instr("sthu", RSxDxRA)
  799.         |  46: Instr("lmw", RTxDxRA)
  800.         |  47: Instr("stmw", RSxDxRA)
  801.         |  48: Instr("lfs", FRTxDxRA)
  802.         |  49: Instr("lfsu", FRTxDxRA)
  803.         |  50: Instr("lfd", FRTxDxRA)
  804.         |  51: Instr("lfdu", FRTxDxRA)
  805.         |  52: Instr("stfs", FRSxDxRA)
  806.         |  53: Instr("stfsu", FRSxDxRA)
  807.         |  54: Instr("stfd", FRSxDxRA)
  808.         |  55: Instr("stfdu", FRSxDxRA)
  809.         |  59:    (* PowerPC single precision FP *)
  810.                 CASE ASH(instr MOD 64, -1) OF
  811.                    18: Instr("fdivs", FRTxFRAxFRBxRc)
  812.                 |  20: Instr("fsubs", FRTxFRAxFRBxRc)
  813.                 |  21: Instr("fadds", FRTxFRAxFRBxRc)
  814.                 |  25: Instr("fmuls", FRTxFRAxFRCxRc)
  815.                 |  28: Instr("fmsubs", FRTxFRAxFRCxFRBxRc)
  816.                 |  29: Instr("fmadds", FRTxFRAxFRCxFRBxRc)
  817.                 |  30: Instr("fnmsubs", FRTxFRAxFRCxFRBxRc)
  818.                 |  31: Instr("fnmadds", FRTxFRAxFRCxFRBxRc)
  819.                 ELSE
  820.                 END
  821.         |  63: DecodeX2(instr)
  822.         |  0: error
  823.         ELSE error
  824.         END
  825.     END DecodeInstr;
  826.     PROCEDURE DumpInt (VAR R: Files.Rider; comment: ARRAY OF CHAR); 
  827.         VAR i: INTEGER;
  828.     BEGIN
  829.         ReadInt(R, i); Texts.Write(W, tab); Texts.WriteString(W, comment);
  830.         Texts.WriteString(W, ": "); Texts.WriteInt(W, i, 0); Texts.WriteLn(W)
  831.     END DumpInt;
  832.     PROCEDURE DumpIntS (VAR R: Files.Rider; comment: ARRAY OF CHAR; VAR i: INTEGER); 
  833.     BEGIN
  834.         ReadInt(R, i); Texts.Write(W, tab); Texts.WriteString(W, comment);
  835.         Texts.WriteString(W, ": "); Texts.WriteInt(W, i, 0); Texts.WriteLn(W)
  836.     END DumpIntS;
  837.     PROCEDURE DumpLongInt (VAR R: Files.Rider; comment: ARRAY OF CHAR);
  838.         VAR i: LONGINT;
  839.     BEGIN
  840.         ReadLInt(R, i); Texts.Write(W, tab); Texts.WriteString(W, comment);
  841.         Texts.WriteString(W, ": "); Texts.WriteInt(W, i, 0); Texts.WriteLn(W);
  842.     END DumpLongInt;
  843.     PROCEDURE DumpHex (VAR R: Files.Rider; comment: ARRAY OF CHAR);
  844.         VAR i: LONGINT;
  845.     BEGIN
  846.         ReadLInt(R, i); Texts.Write(W, tab); Texts.WriteString(W, comment);
  847.         Texts.WriteString(W, ": "); Texts.WriteHex(W, i); Texts.Write(W, "H"); Texts.WriteLn(W)
  848.     END DumpHex;
  849.     PROCEDURE WriteName (VAR R: Files.Rider);
  850.             VAR s: ARRAY 64 OF CHAR; ch: CHAR; i: INTEGER;
  851.     BEGIN
  852.         i := 0; REPEAT Files.Read(R, ch); s[i] := ch; INC(i) UNTIL ch = 0X;
  853.         Texts.WriteString(W, s)
  854.     END WriteName;
  855.     PROCEDURE WriteInt (VAR R: Files.Rider);
  856.         VAR i: INTEGER;
  857.     BEGIN
  858.         ReadInt(R, i); Texts.WriteInt(W, i, 0)
  859.     END WriteInt;
  860.     PROCEDURE WriteLongInt (VAR R: Files.Rider);
  861.         VAR i: LONGINT;
  862.     BEGIN
  863.         ReadLInt(R, i); Texts.WriteInt(W, i, 0)
  864.     END WriteLongInt;
  865.     PROCEDURE WriteHex (VAR R: Files.Rider);
  866.         VAR i: INTEGER;
  867.     BEGIN
  868.         ReadInt(R, i); Texts.WriteHex(W, i)
  869.     END WriteHex;
  870.     PROCEDURE WriteLongHex (VAR R: Files.Rider);
  871.         VAR i: LONGINT;
  872.     BEGIN
  873.         ReadLInt(R, i); Texts.WriteHex(W, i)
  874.     END WriteLongHex;
  875.     PROCEDURE DumpName (VAR R: Files.Rider; comment: ARRAY OF CHAR);
  876.         VAR s: ARRAY 64 OF CHAR; ch: CHAR; i: INTEGER;
  877.     BEGIN
  878.         i := 0; REPEAT Files.Read(R, ch); s[i] := ch; INC(i) UNTIL ch = 0X;
  879.         Texts.Write(W, tab); Texts.WriteString(W, comment); Texts.WriteString(W, ": "); 
  880.         Texts.WriteString(W, s); Texts.WriteLn(W)
  881.     END DumpName;
  882.     PROCEDURE ReadCompInt (VAR R: Files.Rider; VAR i: LONGINT);
  883.         VAR n: LONGINT; s: SHORTINT; x: CHAR;
  884.     BEGIN s := 0; n := 0; Files.Read(R, x);
  885.         WHILE ORD(x) >= 128 DO INC(n, ASH(ORD(x) - 128, s)); INC(s, 7); Files.Read(R, x) END;
  886.         i := n + ASH(ORD(x) MOD 64 - ORD(x) DIV 64 * 64, s)
  887.     END ReadCompInt;
  888.     PROCEDURE OverReadTypes (VAR r: Files.Rider);   (* MK *)
  889.         VAR n: LONGINT; ch: CHAR;
  890.     BEGIN
  891.         Files.Read (r, ch);
  892.         IF ch = CHR (ProcTyp) THEN ReadCompInt (r, n)
  893.         ELSIF ch = 0FX THEN ReadCompInt (r, n); ReadCompInt (r, n); OverReadTypes (r)
  894.         ELSIF ch = 10X THEN Files.Read (r, ch); ReadCompInt (r, n)
  895.         ELSIF ch = 11X THEN ReadCompInt (r, n); OverReadTypes (r)
  896.         ELSIF ch = CHR (Pointer) THEN OverReadTypes (r)
  897.         END;
  898.     END OverReadTypes;
  899.     PROCEDURE DumpRefs (VAR R: Files.Rider; VAR nextProc: LONGINT);
  900.         VAR ch: CHAR; fsize, psize, ralloc, calloc, falloc: LONGINT; leaf: BOOLEAN;
  901.     BEGIN
  902.         ReadCompInt(R, nextProc); nextProc := nextProc*4;
  903.         IF nextProc # 0 THEN    (* fix, if there are no references *)
  904.             Texts.WriteLn(W); Texts.WriteString(W, "PROCEDURE ");
  905.             ReadCompInt(R, fsize); ReadCompInt(R, psize); ReadCompInt(R, ralloc);
  906.             ReadCompInt(R, falloc); ReadCompInt(R, calloc); Files.Read(R, SYSTEM.VAL(SYSTEM.BYTE, leaf));
  907.             Files.Read(R, ch);
  908.             REPEAT Texts.Write(W, ch); Files.Read(R, ch) UNTIL ch = 0X;
  909.             Files.Read(R, ch);
  910.             WHILE (ch # 0F8X) & ~R.eof DO (* MK extended reference info *)
  911.                 Files.Read(R, ch);
  912.                 REPEAT Files.Read(R, ch) UNTIL ch = 0X;
  913.                 ReadCompInt(R, fsize);
  914.                 OverReadTypes (R);
  915.                 Files.Read (R, ch)
  916.             END;
  917.             Texts.WriteString(W, ": fsize = "); Texts.WriteInt(W, fsize, 0);
  918.             Texts.WriteString(W, ", psize = "); Texts.WriteInt(W, psize, 0);
  919.             Texts.WriteString(W, ", ralloc = "); Texts.WriteInt(W, ralloc, 0);
  920.             Texts.WriteString(W, ", falloc = "); Texts.WriteInt(W, falloc, 0);
  921.             Texts.WriteString(W, ", calloc = "); Texts.WriteInt(W, calloc, 0);
  922.             IF leaf THEN Texts.WriteString(W, ", LEAF") ELSE Texts.WriteString(W, ", NON-LEAF") END;
  923.             Texts.WriteLn(W)
  924.         END
  925.     END DumpRefs;
  926.     PROCEDURE Decode*; 
  927.         VAR
  928.             f: Files.File; R, Ref: Files.Rider; S: Texts.Scanner; text, wtext: Texts.Text; v: Viewers.Viewer;
  929.             i, pos, codesize, datasize, lastProc: LONGINT;
  930.             x, y, entno, nofcom, nofrec, nofptrs, nofGmod, noflk, code, const, noftraps: INTEGER; ch: CHAR;
  931.             invRef: BOOLEAN;
  932.             nofmth, nofnewmth, nofinhmth: INTEGER;
  933.             name: ARRAY 64 OF CHAR;
  934.     BEGIN
  935.         Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); f := NIL;
  936.         IF (S.class = Texts.Char) & (S.c = "^") THEN
  937.             Oberon.GetSelection(text, pos, codesize, datasize);
  938.             IF datasize > 0 THEN Texts.OpenScanner(S, text, pos); Texts.Scan(S) END
  939.         END;
  940.         IF S.class = Texts.Name THEN
  941.             i := 0;
  942.             WHILE (S.s[i] # 0X) & (S.s[i] # ".") DO INC(i) END;
  943.             IF S.s[i] = 0X THEN S.s[i] := "." END;
  944.             S.s[i+1] := "O"; S.s[i+2] := "b"; S.s[i+3] := "j"; S.s[i+4] := 0X;
  945.             f := Files.Old(S.s);
  946.             wtext := TextFrames.Text("");
  947.             IF f # NIL THEN
  948.                 Oberon.AllocateUserViewer(Oberon.Mouse.X, x, y);
  949.                 COPY(S.s, name);
  950.                 i := 0; WHILE name[i] # 0X DO INC(i) END;
  951.                 name[i] := "."; name[i+1] := "D"; name[i+2] := "e"; name[i+3] := "c"; name[i+4] := 0X;
  952.                 v := MenuViewers.New(
  953.                             TextFrames.NewMenu(name, "System.Close  System.Copy  System.Grow  Edit.Search  Edit.Store "), 
  954.                             TextFrames.NewText(wtext, 0), TextFrames.menuH, x, y);
  955.                 Files.Set(R, f, 0); pc := 0; Files.Read(R, ch);
  956.                 (* header *)
  957.                 IF ch = 0F8X THEN
  958.                     Texts.WriteString(W, "HEADER "); Files.Read(R, ch); Texts.Write(W, ch); Texts.WriteLn(W);
  959.                     ReadLInt(R, i); i := Files.Length(f)-i-1; Files.Set(Ref, f, i);
  960.                     Files.Read(Ref, ch); invRef := ch # 8BX;
  961.                     IF invRef THEN Texts.WriteString(W, "invalid REFERENCES"); Texts.WriteLn(W) END;
  962.                     Files.Read(Ref, ch);
  963.                     DumpIntS(R, "Entries", entno); DumpIntS(R, "Commands", nofcom);
  964.                     DumpIntS(R, "Pointers", nofptrs); DumpIntS(R, "Records", nofrec); DumpIntS(R, "Modules", nofGmod);
  965.                     DumpInt(R, "Linktable"); DumpIntS(R, "Links", noflk);
  966.                     DumpLongInt(R, "Datasize"); DumpIntS(R, "Constsize", const); DumpIntS(R, "Codesize (words)", code);
  967.                     DumpIntS(R, "Traps", noftraps);
  968.                     DumpHex(R, "Key"); DumpName(R, "Modulename"); Files.Read(R, ch)
  969.                 ELSE
  970.                     Texts.WriteString(W, "invalid HEADER"); Texts.WriteLn(W);
  971.                     WHILE (ch # 82X) & ~R.eof DO Files.Read(R, ch) END
  972.                 END;
  973.                 Texts.WriteLn(W);
  974.                 (* entry block *)
  975.                 IF ch = 82X THEN
  976.                     Texts.WriteString(W, "ENTRY"); Texts.WriteLn(W); i := 0;
  977.                     WHILE i < entno DO
  978.                         Texts.Write(W, tab); Texts.WriteInt(W, i, 0); Texts.WriteString(W, ": ");
  979.                         ReadInt(R, x); Texts.WriteHex(W, LONG(x)*4); Texts.Write(W, "H");
  980.                         Texts.WriteLn(W); INC(i)
  981.                     END;
  982.                     Files.Read(R, ch)
  983.                 ELSE
  984.                     Texts.WriteString(W, "invalid ENTRY"); Texts.WriteLn(W);
  985.                     WHILE (ch # 83X) & ~R.eof DO Files.Read(R, ch) END
  986.                 END;
  987.                 Texts.WriteLn(W);
  988.                 (* command block *)
  989.                 IF ch = 83X THEN
  990.                     Texts.WriteString(W, "COMMAND"); Texts.WriteLn(W); i := 0;
  991.                     WHILE i < nofcom DO
  992.                         Texts.Write(W, tab); WriteName(R); Texts.WriteString(W, ": "); ReadInt(R, x);
  993.                         Texts.WriteHex(W, LONG(x)*4); Texts.Write(W, "H");
  994.                         Texts.WriteLn(W); INC(i)
  995.                     END;
  996.                     Files.Read(R, ch)
  997.                 ELSE
  998.                     Texts.WriteString(W, "invalid COMMAND"); Texts.WriteLn(W);
  999.                     WHILE (ch # 84X) & ~R.eof DO Files.Read(R, ch) END
  1000.                 END;
  1001.                 Texts.WriteLn(W);
  1002.                 (* pointer block *)
  1003.                 IF ch = 84X THEN
  1004.                     Texts.WriteString(W, "POINTERS"); i := 0;
  1005.                     WHILE i < nofptrs DO
  1006.                         IF i MOD 8 = 0 THEN Texts.WriteLn(W); Texts.Write(W, tab) END;
  1007.                         WriteLongInt(R); Texts.Write(W, " "); INC(i)
  1008.                     END;
  1009.                     Texts.WriteLn(W); Files.Read(R, ch)
  1010.                 ELSE
  1011.                     Texts.WriteString(W, "invalid POINTERS"); Texts.WriteLn(W);
  1012.                     WHILE (ch # 85X) & ~R.eof DO Files.Read(R, ch) END
  1013.                 END;
  1014.                 Texts.WriteLn(W);
  1015.                 (* import block *)
  1016.                 IF ch = 85X THEN
  1017.                     Texts.WriteString(W, "IMPORT"); Texts.WriteLn(W); i := 0;
  1018.                     WHILE i < nofGmod DO
  1019.                         Texts.Write(W, tab); WriteLongHex(R); Texts.WriteString(W, "H "); WriteName(R);
  1020.                         Texts.WriteLn(W); INC(i)
  1021.                     END;
  1022.                     Files.Read(R, ch)
  1023.                 ELSE
  1024.                     Texts.WriteString(W, "invalid IMPORT"); Texts.WriteLn(W);
  1025.                     WHILE (ch # 86X) & ~R.eof DO Files.Read(R, ch) END
  1026.                 END;
  1027.                 Texts.WriteLn(W);
  1028.                 (* link entries *)
  1029.                 IF ch = 86X THEN
  1030.                     Texts.WriteString(W, "LINKS"); Texts.WriteLn(W); i := 0;
  1031.                     WHILE i < noflk DO
  1032.                         Texts.Write(W, tab); Files.Read(R, ch); Texts.Write(W, "("); Texts.WriteInt(W, ORD(ch), 0);
  1033.                         Files.Read(R, ch); Texts.Write(W, ","); Texts.WriteInt(W, ORD(ch), 0); Texts.WriteString(W, "): ");
  1034.                         ReadInt(R, x); x := -x; Texts.WriteHex(W, LONG(x)*4); Texts.Write(W, "H");
  1035.                         Texts.WriteLn(W); INC(i)
  1036.                     END;
  1037.                     Files.Read(R, ch)
  1038.                 ELSE
  1039.                     Texts.WriteString(W, "invalid LINKS"); Texts.WriteLn(W);
  1040.                     WHILE (ch # 87X) & ~R.eof DO Files.Read(R, ch) END
  1041.                 END;
  1042.                 Texts.WriteLn(W);
  1043.                 (* const block *)
  1044.                 IF ch = 87X THEN
  1045.                     Texts.WriteString(W, "CONST (not dumped)"); Files.Set(R, f, Files.Pos(R)+const); Texts.WriteLn(W)
  1046.                 ELSE Texts.WriteString(W, "invalid CONST"); Texts.WriteLn(W)
  1047.                 END;
  1048.                 Texts.WriteLn(W);
  1049.                 WHILE (ch # 88X) & ~R.eof DO Files.Read(R, ch) END;
  1050.                 (* code block *)
  1051.                 IF ch = 88X THEN
  1052.                     Texts.WriteString(W, "CODE"); Texts.WriteLn(W); pc := 0; lastProc := 0;
  1053.                     WHILE pc < LONG(code)*4 DO
  1054.                         IF (pc >= lastProc) & ~invRef THEN DumpRefs(Ref, lastProc) END;
  1055.                         ReadLInt(R, i);
  1056.                         Texts.Write(W, tab); Texts.WriteHex(W, pc); Texts.Write(W, tab); Texts.Write(W, tab);
  1057.                         Texts.WriteHex(W, i); Texts.Write(W, "H"); Texts.Write(W, tab); DecodeInstr(i); Texts.WriteLn(W);
  1058.                         INC(pc, 4)
  1059.                     END;
  1060.                     Texts.WriteLn(W); Files.Read(R, ch)
  1061.                 ELSE
  1062.                     Texts.WriteString(W, "invalid CODE"); Texts.WriteLn(W);
  1063.                     WHILE (ch # 89X) & ~R.eof DO Files.Read(R, ch) END
  1064.                 END;
  1065.                 Texts.WriteLn(W);
  1066.                 (* type descriptors *)
  1067.                 IF ch = 89X THEN
  1068.                     Texts.WriteString(W, "TYPES"); Texts.WriteLn(W); i := 0;
  1069.                     WHILE i < nofrec DO
  1070.                         Texts.Write(W, tab); Texts.WriteString(W, "size="); WriteLongInt(R);
  1071.                         Texts.WriteString(W, ", addr="); WriteInt(R);
  1072.                         Texts.WriteString(W, ", base=("); WriteInt(R); Texts.Write(W,","); WriteInt(R); Texts.Write(W, ")");
  1073.                         Files.ReadBytes(R, nofmth, 2); Files.ReadBytes(R, nofinhmth, 2); Files.ReadBytes(R, nofnewmth, 2);
  1074.                         Files.ReadBytes(R, nofptrs, 2);
  1075.                         Texts.WriteLn(W); Texts.Write(W, tab); Texts.WriteString(W, "name="); WriteName(R);
  1076.                         Texts.WriteLn(W); Texts.Write(W, tab); Texts.WriteInt(W, nofmth, 0);
  1077.                         Texts.WriteString(W, " methods, "); Texts.WriteInt(W, nofinhmth, 0);
  1078.                         Texts.WriteString(W, " inherited, new=(");
  1079.                         x := 0;
  1080.                         WHILE x < nofnewmth DO
  1081.                             WriteInt(R); Texts.Write(W, ":"); WriteInt(R); Texts.Write(W, " "); INC(x)
  1082.                         END;
  1083.                         Texts.Write(W, ")"); Texts.WriteLn(W); Texts.Write(W, tab); Texts.WriteString(W, "ptrtab=");
  1084.                         x := 0;
  1085.                         WHILE x < nofptrs DO
  1086.                             IF x MOD 8 = 7 THEN Texts.WriteLn(W); Texts.Write(W, tab) END;
  1087.                             WriteLongInt(R); Texts.Write(W, " "); INC(x)
  1088.                         END;
  1089.                         Texts.WriteLn(W); INC(i)
  1090.                     END;
  1091.                     Texts.WriteLn(W); Files.Read(R, ch)
  1092.                 ELSE 
  1093.                     Texts.WriteString(W, "invalid TYPES"); Texts.WriteLn(W);
  1094.                     WHILE (ch # 8AX) & ~R.eof DO Files.Read(R, ch) END
  1095.                 END;
  1096.                 Texts.WriteLn(W);
  1097.                 IF ch = 8AX THEN
  1098.                     Texts.WriteString(W, "TRAPS"); Texts.WriteLn(W); i := 0;
  1099.                     WHILE i < noftraps DO
  1100.                         Texts.Write(W, tab); ReadInt(R, x); Texts.WriteHex(W, LONG(x)*4); 
  1101.                         Texts.WriteString(W, "H: "); WriteInt(R); Texts.WriteLn(W); INC(i)
  1102.                     END;
  1103.                     Texts.WriteLn(W)
  1104.                 ELSE
  1105.                     Texts.WriteString(W, "invalid TRAPS"); Texts.WriteLn(W)
  1106.                 END
  1107.             ELSE
  1108.                 Texts.WriteString(W, S.s); Texts.WriteString(W, " not found"); Texts.WriteLn(W)
  1109.             END;
  1110.             Texts.Append(wtext, W.buf)
  1111.         END
  1112.     END Decode;
  1113. BEGIN Texts.OpenWriter(W)
  1114. END Decoder.Decode ^
  1115.